﻿using Com.Ctrip.Framework.Apollo;
using Consul;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Primitives;
using Repository.communal;
using Sell.Api.Write;
using Sell.Repository.Interface;
using Sell.Repository.lmpl;
using Sell.Services.Contracts;
using Sell.Services.Customers;
using Sell.Services.Goods;
using Sell.Services.Phrases;
using Sell.Services.Pro;
using Sell.Services.Suppliers;
using Sell.Services.Verifications;
using Sell.Services.Workorders;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.Elasticsearch;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
        options.JsonSerializerOptions.PropertyNamingPolicy = null; // 保持原始属性名
    });
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddDbContext<MyDbContext>(options =>
                options.UseMySql(
                    builder.Configuration.GetValue<string>("kmh"),
                    new MySqlServerVersion(new Version(9, 4)) // ָ�� MySQL �汾
                )
            );
builder.Services.AddAutoMapper(typeof(AutoMeppers));
builder.Services.AddScoped<ISupplierServices, SupplierServices>();
builder.Services.AddScoped<ICustomerServices, CustomerServices>();
builder.Services.AddScoped<IVerificationServices, VerificationServices>();
builder.Services.AddScoped<IContractServices, ContractServices>();
builder.Services.AddScoped<IPhrasesServices, PhrasesServices>();
builder.Services.AddScoped<IProServices, ProServices>();
builder.Services.AddScoped<IFlowServices, FlowServices>();
builder.Services.AddScoped<IGoodsServices, GoodsServices>();
builder.Services.AddScoped<IGoodRepository, GoodRepository>();
builder.Services.AddScoped<IWorkorderServices, WorkorderServices>();
builder.Services.AddScoped<IWorkorderRepository, WorkorderRepository>();
builder.Services.AddScoped<IFlowRepository, FlowRepository>();
builder.Services.AddScoped<IProRepository, ProRepository>();
builder.Services.AddScoped<IPhraseRepository, PhraseRepository>();
builder.Services.AddScoped<ICustomerRepository, CustomerRepository>();
builder.Services.AddScoped<IContractsRepository, ContractRepository>();
builder.Services.AddScoped<ISupplierRepository, SupplierRepository>();
builder.Services.AddScoped<IVerificationRepository, VerificationRepository>();
// ע�� MediatR��������ǰ���򼯺� Application ����
builder.Services.AddMediatR(cfg => {
    cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());

});

//Elk
var configuration = builder.Configuration;
var elaUri = configuration["ELK:ElaticSearchUrl"]; 
var userName = configuration["ELK:UserName"];
var password = configuration["ELK:Password"]; 
Log.Logger = new LoggerConfiguration().MinimumLevel.Information().
    MinimumLevel.Override("Microsoft", LogEventLevel.Warning).
    Enrich.FromLogContext().Enrich.WithMachineName().
    Enrich.WithThreadId().Enrich.WithProcessId().
    WriteTo.Console(new Serilog.Formatting.Compact.CompactJsonFormatter()).
    WriteTo.File("logs/SellApiWrite-.txt", rollingInterval: RollingInterval.
    Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
    .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri(elaUri)) 
    { IndexFormat = "SellApiWrite-logs-{0:yyyy.MM.dd}", AutoRegisterTemplate = true,
        AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7, 
        ModifyConnectionSettings = conn => conn.BasicAuthentication(userName, password),
        BufferBaseFilename = "./logs/serilog-buffer", Period = TimeSpan.FromSeconds(2) }).CreateLogger();
builder.Host.UseSerilog();


//网关
static void RegisterConsul()
{
    try
    {
        var consulClient = new ConsulClient(p => {
            p.Address = new Uri("http://115.190.167.248:8500");//主机ip:8500
        });
        // 2. 确保健康检查端点可访问
        var httpCheck = new AgentServiceCheck()
        {
            DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
            Interval = TimeSpan.FromSeconds(10),
            HTTP = "http://101.37.25.1:8004/WeatherForecast", // 确认此端口服务是否运行,WeatherForecast是天气预报控制器，如果没有这个控制器可以手动创建一个
            Timeout = TimeSpan.FromSeconds(5)
        };
        // 3. 添加标签方便识别
        var registration = new AgentServiceRegistration()
        {
            Checks = new[] { httpCheck },
            ID = $"sellwrite-{Guid.NewGuid()}", // 更易读的ID
            Name = "sellwrite",                // 业务api名称,必须小写
            Address = "101.37.25.1",                   // 纯IP正确
            Port = 8003,                               // 端口与健康检查一致
            Tags = new[] { "dotnet-service" }           // 添加标签
        };

        // 4. 添加错误处理
        var result = consulClient.Agent.ServiceRegister(registration).Result;
        Console.WriteLine($"服务注册成功! Status: {result.StatusCode}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Consul注册失败: {ex.Message}");
    }
}

builder.Configuration.AddApollo
    (builder.Configuration.GetSection("Apollo")).AddDefault().AddNamespace("systemread");


var app = builder.Build();


if (app.Configuration is IConfigurationRoot configurationRoot)
{
    ChangeToken.OnChange(
        () => configurationRoot.GetReloadToken(),
        () => Console.WriteLine($"配置已更新:{app.Configuration.GetValue<string>("kmh")}"));
}





RegisterConsul();


// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    
}
app.UseSwagger();
app.UseSwaggerUI();
app.UseAuthorization();

app.MapControllers();

app.Run();